<?php

class IDbRecordSet extends IMagicObject implements IIterable,Countable,ArrayAccess {
	private $records = array();
	/**
	 * Enter description here...
	 *
	 * @var IDAO
	 */
	private $dao;
	
	public function __construct($dao) {
		$this->dao = $dao;
	}
	
	public function first() {
		return $this->record(0);
	}
	
	public function last() {
		$records = $this->records;
		if (empty($records)) {
			return null;
		}
		$record = array_pop($records);
		if (!isInstanceOf($record, "IDbRecord")) {
			$record = $this->dao->create($record);
		}
		return $record;
	}
	
	public function delete($deep = false) {
		$count = 0;
		foreach ($this->records as $record) {
			if (isInstanceOf($record, "IDbRecord")) {
				$count += $record->delete($deep);
			}
			else if (is_array($record)) {
				$record = $this->dao->create($record);
				$count += $record->delete($deep);
			}
		}
		return $count;
	}
	
	public function remove($index) {
		if (isset($this->records[$index])) {
			unset($this->records[$index]);
		}
	}
	
	public function add($record) {
		$this->records[] = $record;
	}
	
	public function record($index) {
		if (!isset($this->records[$index])) {
			return null;
		}
		$record = $this->records[$index];
		$original = null;
		if (!isInstanceOf($record, "IDbRecord")) {
			$original = $record;
			$record = $this->dao->create($record);
		}
		else {
			$original = $record->attrs();
		}
		$record->_before_read();
		$record->setOriginal($original);
		$record->setAction("read");
		$record->setSaved(true);
		$record->_after_read();
		return $record;
	}
	
	public function arrays() {
		$records = $this->records;
		foreach ($records as $key => $record) {
			if (isInstanceOf($record, "IDbRecord")) {
				$records[$key] = $record->attrs();
			}
		}
		return $records;
	}
	
	public function records() {
		$records = $this->records;
		foreach ($records as $key => $record) {
			if (!isInstanceOf($record, "IDbRecord")) {
				$records[$key] = $this->dao->create($record);
			}
		}
		return $records;
	}
	
	public function setRecords(array $records = null) {
		if ($records == null) {
			return;
		}
		$this->records = arrayJoin($this->records, $records);
	}
	
	public function count() {
		return count($this->records);
	}
	
	public function toArray() {
		return $this->records;
	}
	
	public function getIterator() {
		return new IListIterator($this->records);
	}
	
	/**
	 * 判断一个偏移量是否存在
	 *
	 * 实现了 ArrayAccess 接口对应方法
	 * 
	 * @param integer $index
	 * @return boolean
	 */
	public function offsetExists($index) {
		return array_key_exists($index, $this->records);
	}
	
	/**
	 * 从一个偏移量中取得数据
	 * 
	 * 实现了 ArrayAccess 接口对应方法
	 *
	 * @param integer $index 偏移量
	 * @return mixed
	 */
	public function offsetGet($index) {
		return $this->record($index);
	}
	
	/**
	 * 设置偏移量位置上的值
	 *
	 * 实现了 ArrayAccess 接口对应方法
	 * 
	 * @param integer $index 偏移量
	 * @param mixed $item 值
	 */
	public function offsetSet($index, $item) {
		$this->records[$index] = $item;
	}
	
	/**
	 * 删除偏移量位置对应的元素
	 * 
	 * 实现了 ArrayAccess 接口对应方法
	 *
	 * @param integer $index 偏移量
	 */
	public function offsetUnset($index) {
		$this->remove($index);
	}	
}

?>